﻿// Red and Black POJ - 1979.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <queue>
#include <vector>

using namespace std;
//https://vjudge.csgrandeur.cn/problem/POJ-1979
/*
这是一个被方形瓷砖覆盖的长方形房间。每个瓷砖可以是红色或黑色。
一个人站在一块黑色的瓷砖上。从一个瓷砖出发，他可以移动到四个相邻的瓷砖之一。
但他不能移动到红色的瓷砖上，只能在黑色的瓷砖上移动。

编写一个程序来计算他可以通过重复上述移动到达的黑色瓷砖的数量。
输入
输入包含多个数据集。一个数据集以包含两个正整数W和H的行开始；W和H分别表示水平和垂直方向上的瓷砖数量。
W和H均不超过20。

数据集中还有H行，每行包含W个字符。每个字符代表一个瓷砖的颜色，具体如下：

'.' - 黑色瓷砖
'#' - 红色瓷砖
'@' - 人站在黑色瓷砖上（数据集中仅出现一次）
输入的结束由包含两个零的行表示。
输出
对于每个数据集，程序应输出一行，其中包含他可以从初始瓷砖到达的瓷砖数量（包括初始瓷砖本身）。

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0


45
59
6
13


*/


const int N = 30;
char gra[N][N];
int startx, starty;
int h, w;

const int addx[] = { 1,-1,0,0 };
const int addy[] = { 0,0,1,-1 };

void solve() {
	int ans = 1;
	queue<vector<int> > q;
	vector<int> v; v.push_back(startx); v.push_back(starty);
	q.push(v);
	gra[startx][starty] = '0';

	while (!q.empty()) {
		int x = q.front()[0];
		int y = q.front()[1];
		q.pop();

		

		for (int i = 0; i < 4; i++) {
			int newx = x + addx[i]; int newy = y + addy[i];
			if(newx>=0 && newx<h && newy>=0 && newy<w && gra[newx][newy] == '.') {
				ans++;
				gra[newx][newy] = '0';
				vector<int> v; v.push_back(newx); v.push_back(newy);
				q.push(v);
			}
		}
	}

	cout << ans << endl;
}


int main()
{
	while (cin >> w >> h) {
		if (0 == h && 0 == w) break;
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> gra[i][j];
				if ('@' == gra[i][j]) {startx = i; starty = j;}
			}
		}

		solve();
	}


	return 0;
}

 